//===================================================================
// 项目名 : Hbt.Cur
// 文件名 : ParallelWorkflowEngine.cs
// 创建者 : Claude
// 创建时间: 2024-12-01
// 版本号 : V0.0.1
// 描述    : 并行工作流引擎实现
//===================================================================

namespace Hbt.Application.Services.Workflow.Engine.Parallel
{
    /// <summary>
    /// 并行工作流引擎实现
    /// </summary>
    public class HbtParallelWorkflowEngine : IHbtParallelWorkflowEngine
    {
        private readonly IHbtRepositoryFactory _repositoryFactory;
        private readonly IHbtWorkflowEngine _workflowEngine;
        private readonly IHbtLogger _logger;
        private readonly IHbtCurrentUser _currentUser;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="repositoryFactory">仓储工厂</param>
        /// <param name="workflowEngine">工作流引擎</param>
        /// <param name="logger">日志服务</param>
        /// <param name="currentUser">当前用户服务</param>
        public HbtParallelWorkflowEngine(
            IHbtRepositoryFactory repositoryFactory,
            IHbtWorkflowEngine workflowEngine,
            IHbtLogger logger,
            IHbtCurrentUser currentUser)
        {
            _repositoryFactory = repositoryFactory;
            _workflowEngine = workflowEngine;
            _logger = logger;
            _currentUser = currentUser;
        }

        /// <summary>
        /// 创建并行分支
        /// </summary>
        public async Task<List<long>> CreateParallelBranchesAsync(long instanceId, HbtParallelBranchConfigDto branchConfig)
        {
            try
            {
                var branchInstances = new List<long>();
                var mainInstance = await GetInstanceRepository().GetByIdAsync(instanceId);

                if (mainInstance == null)
                    throw new InvalidOperationException("主工作流实例不存在");

                // 创建并行分支实例
                foreach (var branch in branchConfig.Branches)
                {
                    var branchInstance = new HbtInstance
                    {
                        SchemeId = branch.SchemeId,
                        InstanceTitle = $"{mainInstance.InstanceTitle}-{branch.BranchName}",
                        BusinessKey = $"{mainInstance.BusinessKey}-{branch.BranchKey}",
                        InitiatorId = mainInstance.InitiatorId,
                        CurrentNodeId = branch.StartNodeId,
                        CurrentNodeName = branch.StartNodeName,
                        Status = 1, // 运行中
                        StartTime = DateTime.Now,
                        Variables = branch.Variables,
                        Priority = mainInstance.Priority,
                        Urgency = mainInstance.Urgency
                    };

                    await GetInstanceRepository().CreateAsync(branchInstance);
                    branchInstances.Add(branchInstance.Id);

                    // 记录分支创建历史
                    await CreateParallelBranchRecordAsync(instanceId, branchInstance.Id, branch.BranchName, "分支创建");
                }

                // 更新主实例状态为并行执行
                mainInstance.Status = 5; // 5 表示并行执行中
                await GetInstanceRepository().UpdateAsync(mainInstance);

                _logger.Info($"并行分支创建成功，主实例: {instanceId}, 分支数量: {branchInstances.Count}");
                return branchInstances;
            }
            catch (Exception ex)
            {
                _logger.Error($"创建并行分支失败: {ex.Message}", ex);
                throw;
            }
        }

        /// <summary>
        /// 检查并行分支完成状态
        /// </summary>
        public async Task<HbtParallelBranchStatusDto> CheckBranchStatusAsync(long instanceId)
        {
            try
            {
                var mainInstance = await GetInstanceRepository().GetByIdAsync(instanceId);
                if (mainInstance == null)
                    throw new InvalidOperationException("主工作流实例不存在");

                // 获取所有分支实例
                var branchInstances = await GetInstanceRepository().GetListAsync(x =>
                    x.BusinessKey.StartsWith(mainInstance.BusinessKey + "-") &&
                    x.Id != instanceId);

                var completedBranches = branchInstances.Count(x => x.Status == 2); // 已完成
                var runningBranches = branchInstances.Count(x => x.Status == 1); // 运行中
                var suspendedBranches = branchInstances.Count(x => x.Status == 3); // 已暂停
                var terminatedBranches = branchInstances.Count(x => x.Status == 4); // 已终止

                var totalBranches = branchInstances.Count;
                var isAllCompleted = completedBranches == totalBranches;

                return new HbtParallelBranchStatusDto
                {
                    InstanceId = instanceId,
                    TotalBranches = totalBranches,
                    CompletedBranches = completedBranches,
                    RunningBranches = runningBranches,
                    SuspendedBranches = suspendedBranches,
                    TerminatedBranches = terminatedBranches,
                    IsAllCompleted = isAllCompleted,
                    CompletionPercentage = totalBranches > 0 ? (double)completedBranches / totalBranches * 100 : 0
                };
            }
            catch (Exception ex)
            {
                _logger.Error($"检查并行分支状态失败: {ex.Message}", ex);
                throw;
            }
        }

        /// <summary>
        /// 等待并行分支汇聚
        /// </summary>
        public async Task<bool> WaitForParallelJoinAsync(long instanceId, TimeSpan timeout)
        {
            try
            {
                var startTime = DateTime.Now;

                while (DateTime.Now - startTime < timeout)
                {
                    var status = await CheckBranchStatusAsync(instanceId);

                    if (status.IsAllCompleted)
                    {
                        // 所有分支完成，执行汇聚逻辑
                        await ExecuteParallelJoinAsync(instanceId);
                        return true;
                    }

                    // 等待一段时间再检查
                    await Task.Delay(1000); // 1秒检查一次
                }

                _logger.Warn($"并行分支汇聚超时，实例ID: {instanceId}");
                return false;
            }
            catch (Exception ex)
            {
                _logger.Error($"等待并行分支汇聚失败: {ex.Message}", ex);
                return false;
            }
        }

        /// <summary>
        /// 处理并行分支完成
        /// </summary>
        public async Task<bool> HandleBranchCompletionAsync(long branchInstanceId)
        {
            try
            {
                var branchInstance = await GetInstanceRepository().GetByIdAsync(branchInstanceId);
                if (branchInstance == null)
                    return false;

                // 查找主实例
                var mainInstanceKey = branchInstance.BusinessKey.Substring(0, branchInstance.BusinessKey.LastIndexOf('-'));
                var mainInstance = await GetInstanceRepository().GetFirstAsync(x => x.BusinessKey == mainInstanceKey);

                if (mainInstance == null)
                    return false;

                // 检查是否所有分支都完成
                var status = await CheckBranchStatusAsync(mainInstance.Id);

                if (status.IsAllCompleted)
                {
                    // 执行汇聚逻辑
                    await ExecuteParallelJoinAsync(mainInstance.Id);
                }

                return true;
            }
            catch (Exception ex)
            {
                _logger.Error($"处理并行分支完成失败: {ex.Message}", ex);
                return false;
            }
        }

        /// <summary>
        /// 获取并行分支信息
        /// </summary>
        public async Task<HbtParallelWorkflowInfoDto> GetParallelWorkflowInfoAsync(long instanceId)
        {
            try
            {
                var mainInstance = await GetInstanceRepository().GetByIdAsync(instanceId);
                if (mainInstance == null)
                    throw new InvalidOperationException("主工作流实例不存在");

                // 获取所有分支实例
                var branchInstances = await GetInstanceRepository().GetListAsync(x =>
                    x.BusinessKey.StartsWith(mainInstance.BusinessKey + "-") &&
                    x.Id != instanceId);

                var branchInfos = branchInstances.Select(x => new HbtParallelBranchInfoDto
                {
                    BranchInstanceId = x.Id,
                    BranchName = x.InstanceTitle.Replace(mainInstance.InstanceTitle + "-", ""),
                    Status = x.Status,
                    CurrentNodeName = x.CurrentNodeName,
                    StartTime = x.StartTime,
                    EndTime = x.EndTime,
                    Progress = CalculateBranchProgress(x)
                }).ToList();

                return new HbtParallelWorkflowInfoDto
                {
                    MainInstanceId = instanceId,
                    MainInstanceTitle = mainInstance.InstanceTitle,
                    MainInstanceStatus = mainInstance.Status,
                    Branches = branchInfos,
                    TotalBranches = branchInfos.Count,
                    CompletedBranches = branchInfos.Count(x => x.Status == 2),
                    RunningBranches = branchInfos.Count(x => x.Status == 1)
                };
            }
            catch (Exception ex)
            {
                _logger.Error($"获取并行分支信息失败: {ex.Message}", ex);
                throw;
            }
        }

        /// <summary>
        /// 强制汇聚并行分支
        /// </summary>
        public async Task<bool> ForceJoinBranchesAsync(long instanceId, string reason)
        {
            try
            {
                var mainInstance = await GetInstanceRepository().GetByIdAsync(instanceId);
                if (mainInstance == null)
                    return false;

                // 获取所有未完成的分支
                var branchInstances = await GetInstanceRepository().GetListAsync(x =>
                    x.BusinessKey.StartsWith(mainInstance.BusinessKey + "-") &&
                    x.Id != instanceId &&
                    x.Status != 2); // 不是已完成状态

                // 强制终止未完成的分支
                foreach (var branch in branchInstances)
                {
                    branch.Status = 4; // 已终止
                    branch.EndTime = DateTime.Now;
                    await GetInstanceRepository().UpdateAsync(branch);

                    // 记录强制终止操作
                    await CreateParallelBranchRecordAsync(instanceId, branch.Id, "强制终止", reason);
                }

                // 执行汇聚逻辑
                await ExecuteParallelJoinAsync(instanceId);

                _logger.Info($"强制汇聚并行分支成功，实例ID: {instanceId}, 原因: {reason}");
                return true;
            }
            catch (Exception ex)
            {
                _logger.Error($"强制汇聚并行分支失败: {ex.Message}", ex);
                return false;
            }
        }

        #region 私有方法

        /// <summary>
        /// 执行并行汇聚
        /// </summary>
        private async Task ExecuteParallelJoinAsync(long instanceId)
        {
            try
            {
                var mainInstance = await GetInstanceRepository().GetByIdAsync(instanceId);
                if (mainInstance == null)
                    return;

                // 更新主实例状态为运行中
                mainInstance.Status = 1; // 运行中
                await GetInstanceRepository().UpdateAsync(mainInstance);

                // 记录汇聚历史
                await CreateParallelBranchRecordAsync(instanceId, 0, "汇聚完成", "所有并行分支已完成");

                _logger.Info($"并行分支汇聚完成，实例ID: {instanceId}");
            }
            catch (Exception ex)
            {
                _logger.Error($"执行并行汇聚失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 创建并行分支记录
        /// </summary>
        private async Task CreateParallelBranchRecordAsync(long mainInstanceId, long branchInstanceId, string action, string remark)
        {
            try
            {
                var record = new HbtInstanceOper
                {
                    InstanceId = mainInstanceId,
                    NodeId = "parallel",
                    NodeName = "并行分支",
                    OperType = 9, // 9 表示并行操作
                    OperatorId = _currentUser.UserId,
                    OperatorName = _currentUser.UserName,
                    OperOpinion = $"{action}: {remark}",
                    OperData = JsonConvert.SerializeObject(new { BranchInstanceId = branchInstanceId, Action = action })
                };

                await GetOperRepository().CreateAsync(record);
            }
            catch (Exception ex)
            {
                _logger.Error($"创建并行分支记录失败: {ex.Message}", ex);
            }
        }

        /// <summary>
        /// 计算分支进度
        /// </summary>
        private double CalculateBranchProgress(HbtInstance branchInstance)
        {
            if (branchInstance.Status == 2) // 已完成
                return 100.0;

            if (branchInstance.Status == 4) // 已终止
                return 0.0;

            // 这里可以根据实际业务逻辑计算进度
            // 暂时返回默认值
            return branchInstance.Status == 1 ? 50.0 : 0.0;
        }

        /// <summary>
        /// 获取实例仓储
        /// </summary>
        private IHbtRepository<HbtInstance> GetInstanceRepository()
        {
            return _repositoryFactory.GetWorkflowRepository<HbtInstance>();
        }

        /// <summary>
        /// 获取操作记录仓储
        /// </summary>
        private IHbtRepository<HbtInstanceOper> GetOperRepository()
        {
            return _repositoryFactory.GetWorkflowRepository<HbtInstanceOper>();
        }

        #endregion
    }
}
